package com.huakai.springenv.controller;

import brave.Span;
import brave.Tracer;
import brave.propagation.TraceContextOrSamplingFlags;
import com.huakai.springenv.aspect.profiler.DBTimeProfile;
import com.huakai.springenv.service.impl.timeprofiler.TimeProfilerService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@RestController
public class TestController {

    @Resource
    private Tracer tracer;

    @Resource
    private TimeProfilerService timeProfilerService;


    private AtomicInteger count = new AtomicInteger();

    private static Logger ACCESS_LOG = LoggerFactory.getLogger("duiba_access_log");

    @RequestMapping("/test")
    public String test() {
        return "ok";
    }

    @RequestMapping("/testSleuth")
    public String testSleuth(){
        log.info("test Sleuth");

        // 获取当前线程的 Span
        Span currentSpan = tracer.currentSpan();


        // 创建普通的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(3);


        executorService.execute(() -> {
            // 基于主线程的 traceId 创建一个新的 Span
            Span newSpan = tracer.nextSpan(TraceContextOrSamplingFlags.create(currentSpan.context())).name("async-task").start();
            // 将当前 Span 放入新线程上下文中
            try (Tracer.SpanInScope spanInScope = tracer.withSpanInScope(newSpan)) {
                // 新线程中的日志将包含 traceId 和 spanId
                log.info("New thread-2 log with trace info");
            }
        });
        return "ok";
    }

    @RequestMapping("/testProfiler")
    public void testProfiler(HttpServletRequest request) {
        try {
            DBTimeProfile.start(request);
            timeProfilerService.method();
        }finally {
            DBTimeProfile.end( Thread.currentThread().getStackTrace()[1].getMethodName());
        }
    }

    @RequestMapping(value ="/testAccessLog")
    public void testAccessLog(){
        ACCESS_LOG.info("access log {}",count.incrementAndGet());
    }
}
